package com.baize.cpdepus.common;

import com.baize.cpdepus.exception.ExceptionEnum;
import com.baize.cpdepus.exception.ServiceException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.Map;

/**
 * 响应类
 *
 * @param <T> 指定的数据类型
 */
@Data
@Accessors(chain = true)
@ApiModel("响应类")
@NoArgsConstructor
public class R<T> {

    /**
     * 编码
     */
    @ApiModelProperty(value = "编码", allowableValues = "0,1")
    private Integer code = 1; //编码：1成功，0和其它数字为失败
    /**
     * 错误信息
     */
    @ApiModelProperty(value = "错误信息")
    private String msg = "请求成功!"; //错误信息
    /**
     * 数据
     */
    @ApiModelProperty(value = "数据", allowEmptyValue = true)
    private T data = null; //数据
    /**
     * 动态数据
     */
    @ApiModelProperty(value = "动态数据", allowEmptyValue = true)
    private Map<String, Object> map = new HashMap<>(); //动态数据

    public R(T data) {
        this.data = data;
    }

    public R(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    /**
     * 成功请求
     *
     * @param object 数据
     * @param <T>    类型
     * @return JSON
     */
    public static <T> R<T> success(T object) {
        return new R<>(object);
    }

    /**
     * 自定义错误信息的请求
     *
     * @param msg 消息
     * @param <T> 类型
     * @return JSON
     */
    public static <T> R<T> error(String msg) {
        return new R<>(0, msg);
    }

    /**
     * 指定枚举类型的错误返回
     *
     * @param exceptionEnum 错误枚举
     * @param <T>           类型
     * @return JSON
     */
    public static <T> R<T> error(ExceptionEnum exceptionEnum) {
        return new R<>(exceptionEnum.getStatus(), exceptionEnum.getMessage());
    }

    /**
     * 指定异常的错误返回
     *
     * @param e   异常
     * @param <T> 类型
     * @return JSON
     */
    public static <T> R<T> error(Exception e) {
        int status = 0;
        //如果是自定义的异常则直接获取
        if (e instanceof ServiceException) {
            status = ((ServiceException) e).getStatus();
        }
        return new R<>(status, e.getMessage());
    }

    /**
     * 动态数据插入
     *
     * @param key   键
     * @param value 值
     * @return JSON
     */
    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }
}